#include "stdafx.h"
#include "NakedCallbacks.h"
#include "Profiler.h"
#include "Logger.h"

extern Logger logger;

//
// These are the stub functions which get called by the naked methods below.
//

__forceinline void CProfiler::Enter( FunctionID functionID )
{
	logger.Method(ENTER, functionID, 1);
}

__forceinline void CProfiler::Leave( FunctionID functionID )
{
	logger.Method(LEAVE, functionID, -1);
}

__forceinline void CProfiler::Tailcall( FunctionID functionID )
{
	logger.Method(TAILCALL, functionID, 0); // not yet sure what a tailcall is, so unsure about increment
}

//
// These are the stub functions which get called by the naked methods below.
//

EXTERN_C void __stdcall EnterStub( FunctionID functionID )
{
	CProfiler::Enter( functionID );
}

EXTERN_C void __stdcall LeaveStub( FunctionID functionID )
{
	CProfiler::Leave( functionID );   
}

EXTERN_C void __stdcall TailcallStub( FunctionID functionID )
{
	CProfiler::Tailcall( functionID );
}

//
// These are the naked functions which are called directly by the CLR on Enter/Leave/Tailcall
//

void __declspec( naked ) __stdcall EnterNaked3(FunctionIDOrClientID functionIDOrClientID)
{
	__asm
	{
		push eax
		push ecx
		push edx
		push [esp + 16]
		call EnterStub
		pop edx
		pop ecx
		pop eax
		ret 4
	}
}

void __declspec( naked ) __stdcall LeaveNaked3(FunctionIDOrClientID functionIDOrClientID)
{
	__asm
	{
		push eax
		push ecx
		push edx
		push [esp + 16]
		call LeaveStub
		pop edx
		pop ecx
		pop eax
		ret 4
	}
}

void __declspec( naked ) __stdcall TailcallNaked3(FunctionIDOrClientID functionIDOrClientID)
{
	__asm
	{
		push eax
		push ecx
		push edx
		push [esp + 16]
		call TailcallStub
		pop edx
		pop ecx
		pop eax
		ret 4
	}
}
